package hu.comicsans;

import java.util.Random;

/**
 * Egy dinamikusan mozgó objektum. Maga után folyamatosan szagnyomot hagy. Az élelmiszerraktárhoz
 * érve interakcióba lép vele, egyel csökkenti a benne található táplálékok számát.
 */
public class Hangya extends SikbeliElem implements Frissitheto {

	/**
	 * a hangya tárolja a referenciát a bolyra, amihez tartozik
	 */
	private HangyaBoly enBolyom = null;
	
	/**
	 * a hangya éppen visz-e magával ételt
	 */
	public Boolean vanNalamEtel = false;
	
	/**
	 * egy random szám generátor
	 */
	private Random generator = new Random();
	
	private long hanyadikHivas = 0;
	
	/**
	 * létrehoz egy példányt a hangyából
	 * 
	 * @param boly a boly objektum, amihez a hangya tartozik
	 * @param posX a hangya X koordinátája
	 * @param posY a hangya Y koordinátája
	 */
	public Hangya(HangyaBoly boly, double posX, double posY, double sebX, double sebY) {
		super(posX, posY, 5);

		this.sebesseg = new Vektor(sebX, sebY);
		this.enBolyom = boly;
	}
	
	/**
	 * Ez a metódus rendszeresen meghívódik. Frissíti a hangya helyzetét.
	 */
	@Override
	public void frissit(long te) {
		
		//számoljuk a függvényhívásokat
		hanyadikHivas++;
		
		//ha van szagnyom és nincs nálam étel
		if (enBolyom.szagNyomLista.size() > 0 && !vanNalamEtel)
		{
			//kikeressük a legerősebb szagnyomot
			
			int legErosebb = 0;
			double legErosebbX = 0;
			double legErosebbY = 0;
			
			for (int i=0; i< enBolyom.szagNyomLista.size(); i++)
			{
				SzagNyom s = enBolyom.szagNyomLista.get(i);
				
				if (s.erosseg > legErosebb)
				{
					legErosebb = s.erosseg;
					legErosebbX = s.pozicio.x;
					legErosebbY = s.pozicio.y;
				}
			}
			
			//korrigálunk a legerősebb szagnyom irányába
			
			if (legErosebbX > pozicio.x)
			{
				sebesseg.x += 0.02;
			} else
			{
				sebesseg.x -= 0.02;
			}
			
			if (legErosebbY > pozicio.y)
			{
				sebesseg.y += 0.02;
			} else
			{
				sebesseg.y -= 0.02;
			}
		} else
		if (vanNalamEtel && hanyadikHivas % 25 == 0)
		{
			//korrigálunk a boly irányába
			
			if (enBolyom.pozicio.x > pozicio.x && (enBolyom.pozicio.x - pozicio.x) > 5)
			{			
				sebesseg.x += 0.2*(enBolyom.pozicio.x - pozicio.x);
			} else
			if (enBolyom.pozicio.x < pozicio.x && (pozicio.x - enBolyom.pozicio.x) > 5)
			{
				sebesseg.x -= 0.2*(pozicio.x - enBolyom.pozicio.x);
			}
			
			if (enBolyom.pozicio.y > pozicio.y && (enBolyom.pozicio.y - pozicio.y) > 5)
			{
				sebesseg.y += 0.2*(enBolyom.pozicio.y - pozicio.y);
			} else
			if (enBolyom.pozicio.y < pozicio.y && (pozicio.y - enBolyom.pozicio.y) > 5)
			{
				sebesseg.y -= 0.2*(pozicio.y - enBolyom.pozicio.y);
			}
		} else
		{
			// random elkanyarodunk
			
			if (generator.nextInt(10) > 8)
			{
				sebesseg.x += 0.05;
				sebesseg.y -= 0.05;
			}
			
			if (generator.nextInt(10) > 8)
			{
				sebesseg.x -= 0.05;
				sebesseg.y += 0.05;
			}
		}
		
		//visszapattanunk a pálya szélén
		
		if (pozicio.x + sugar >= Jatek.szelesseg)
		{
			sebesseg.x = -1;
		}
		
		if (pozicio.x - sugar <= 0)
		{
			sebesseg.x = 1;
		}
		
		if (pozicio.y + sugar >= Jatek.magassag)
		{
			sebesseg.y = -1;
		}
		
		if (pozicio.y - sugar <= 0)
		{
			sebesseg.y = 1;
		}
		
		//ha túl nagy a sebesség, normalizáljuk
		
		if (sebesseg.x > 2 || sebesseg.y > 2 || sebesseg.x < -2 || sebesseg.y < -2)
		{
			sebesseg.normalizal();
		}
		
		// a tényleges elmozdulás
		
		pozicio.x += sebesseg.x;
		pozicio.y += sebesseg.y;
	}
	
	/**
	 * ha valaki meghívja ezt a metódust, a hangya meghal
	 */
	public void meghal() {

		//szólunk a bolynak hogy meghaltunk
		enBolyom.hangyaHalal(this);
		
		//eldobjuk a boly referenciát
		this.enBolyom = null;
	}
	
	/**
	 * A hangyának a kaviccsal való ütközését kezeli.
	 * 
	 * @param kavics A kavics, amivel a hangya ütközik.
	 */
	public void utkozesKezelese(Kavics kavics) {
		if (Jatek.ketKorMetsziEgymast(pozicio, sugar, kavics.pozicio, kavics.sugar))
		{
			//ha ütközik a kaviccsal, visszapattan
			
			sebesseg.x *= -1;
			sebesseg.x += 0.2;
			sebesseg.y *= -1;
		}
	}
	
	/**
	 * A hangyának a tócsával való ütközését kezeli. 
	 * 
	 * @param tocsa A tócsa, amivel a hangya ütközik.
	 */
	public void utkozesKezelese(Tocsa tocsa) {
		if (Jatek.ketKorMetsziEgymast(pozicio, sugar, tocsa.pozicio, tocsa.sugar))
		{
			//ha ütközik a tócsával, visszapattan
			
			sebesseg.x *= -1;
			sebesseg.x += 0.2;
			sebesseg.y *= -1;
		}
	}
	
	/**
	 * Kezeli egy élelmiszerraktárral való ütközést. Meghívja a paraméterben megadott
	 * raktár elvesz metódusát, majd az eredménytől függően beállítja a hangya vanNalamEtel
	 * attribútumát, ezzel jelezve, hogy a továbbiakban a hangyánál van táplálék.
	 * 
	 * @param raktar A raktár, amivel a hangya ütközik.
	 */
	public void utkozesKezelese(ElelmiszerRaktar raktar) {
		if (Jatek.ketKorMetsziEgymast(pozicio, sugar, raktar.pozicio, raktar.sugar))
		{
			
			if (!vanNalamEtel && raktar.elvesz())
			{
				vanNalamEtel = true;
				szagnyomotLerak();
			}
		}
		
	}

	/**
	 * A hangyának a hangyabollyal való ütközését kezeli. Ez általában a hangya visszatérését
	 * jelenti táplálékkal.
	 * 
	 * @param hangyaBoly A hangyaboly, amivel a hangya ütközik.
	 */
	public void utkozesKezelese(HangyaBoly hangyaBoly) {

		if (Jatek.ketKorMetsziEgymast(pozicio, sugar, hangyaBoly.pozicio, hangyaBoly.sugar))
		{
			vanNalamEtel = false;
		}
	}

	/**
	 * A hangyának egy mérgezett területtel való ütközését kezeli.
	 * 
	 * @param mt A mérgezett terület, amivel a hangya ütközik.
	 */
	public void utkozesKezelese(MergezettTerulet mt) {
		if (Jatek.ketKorMetsziEgymast(pozicio, sugar, mt.pozicio, mt.sugar))
		{			
			meghal();
		}
	}
	
	/**
	 * Lerak egy új szagnyomot a hangya adott pozíciójára.
	 */
	public void szagnyomotLerak()
	{
		enBolyom.ujSzagnyom(pozicio.x, pozicio.y);
	}
}
